package com.enjoyor.soa.traffic.server.tsms.helper;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.enjoyor.soa.traffic.core.tsms.domain.RltRouteDevice;
import com.enjoyor.soa.traffic.core.tsms.enums.EnumDicPublic;
import com.enjoyor.soa.traffic.server.tsms.dubbo.impl.DubboSchemeRehearseService;
import com.enjoyor.soa.traffic.util.helper.GeoToolsHelper;
import com.enjoyor.soa.traffic.util.helper.TimeHelper;
/**
 * 根据线路分隔数据分析冲突情况
 * @author fzj
 * @date 2019-06-25
 */
public class RouteClashHelper {
	//private static final Logger logger = Logger.getLogger(RouteClashHelper.class);
	/**
	 * 将线路信息按每秒时间进行分解
	 * @param taskRouteList 所有线路信息集合
	 * 		@param taskId 任务ID
	 * 		@param taskName 任务名称
	 * 		@param routeInfo 线路信息
	 * 		@param beginTime 开始执行时间
	 * 		@param endTime 结束执行时间
	 * 		@param startLength 距线路起点距离
	 * @param routeSplitTime 线路拆分时间间隔(ms)
	 * @return
	 */
	@SuppressWarnings({"rawtypes", "unchecked", "unused"})
	public static Map<String, Map<String, Object>> routeClashAnalysis(Map<String, Map<String, Map>> taskByTimeMap,List<Map<String, Object>> taskRouteList, 
			long minBeginLong, long maxEndLong, int routeSplitTime, int timeNum, int clashDistance, boolean isDetail) {
		//整合冲突信息
		Map<String, Map<String, Object>> clashMap = new HashMap<String, Map<String, Object>>();
		try {
			int lockDistance = DubboSchemeRehearseService.lockDistance;
			long allTimeLong = maxEndLong - minBeginLong;
			String routeClashFlag = "";
			String videoClashFlag = "";
			String signalClashFlag = "";

			String time0 = TimeHelper.dateToLongString();
			forOut://最外层循环标签
			for(long timeA = minBeginLong; timeA <= maxEndLong; timeA+=routeSplitTime) {
				long time1 = new Date().getTime();
				if(taskByTimeMap.get(String.valueOf(timeA)) == null) {
					continue;
				}
				taskByTimeMap.get(String.valueOf(timeA)).put("routeClash", new HashMap<String, Object>());
				taskByTimeMap.get(String.valueOf(timeA)).put("videoClash", new HashMap<String, Object>());
				taskByTimeMap.get(String.valueOf(timeA)).put("signalClash", new HashMap<String, Object>());
				forRouteA://线路A循环标签
				for(int a = 0; a < taskRouteList.size()-1; a++){
					Map<String, Object> taskRouteMapA = taskRouteList.get(a);
				    String taskIdA = (String)taskRouteMapA.get("taskId");//执行任务ID
				    Map<String, Object> objectMapA = taskByTimeMap.get(String.valueOf(timeA)).get(taskIdA);
				    if(objectMapA != null) {
				    	double xA = (double)objectMapA.get("x");
					    double yA = (double)objectMapA.get("y");
					    double distanceStartLengthA = (double)objectMapA.get("distanceStartLength");
					    String taskNameA = (String)objectMapA.get("taskName");
					    Map<String, RltRouteDevice> videoMapA = (Map<String, RltRouteDevice>)objectMapA.get("videoMap");
					    Map<String, RltRouteDevice> signalMapA = (Map<String, RltRouteDevice>)objectMapA.get("signalMap");
					    forRouteB://线路B循环标签
					    for(int b = a+1; b < taskRouteList.size(); b++){
							Map<String, Object> taskRouteMapB = taskRouteList.get(b);
						    String taskIdB = (String)taskRouteMapB.get("taskId");//执行任务ID
						    forTime://时间戳循环标签
						    for(long timeB=timeA-timeNum*routeSplitTime; timeB<=timeA+timeNum*routeSplitTime; timeB+=routeSplitTime) {
						    	if(timeB >= minBeginLong && timeB <= maxEndLong) {
						    		if(taskByTimeMap.get(String.valueOf(timeB)) == null) {
						    			continue;
						    		}
						    		Map<String, Object> objectMapB = taskByTimeMap.get(String.valueOf(timeB)).get(taskIdB);
								    if(objectMapB != null) {
								    	//判断车队距离冲突--start
								    	double xB = (double)objectMapB.get("x");
									    double yB = (double)objectMapB.get("y");
									    double distanceStartLengthB = (double)objectMapB.get("distanceStartLength");
									    String taskNameB = (String)objectMapB.get("taskName");
									    double distance = GeoToolsHelper.GetPointDistance(xA, yA, xB, yB);//求两坐标的距离
									    /*String dateStrA = TimeHelper.dateToLongString(new Date(timeA));
									    String dateStrB = TimeHelper.dateToLongString(new Date(timeB));
									    String message = dateStrA + "=A:"+taskIdA +"=" +dateStrB +"=B:"+taskIdB + "xA:"+xA+ "yA:"+yA
									    		+ "xB:"+xB+ "yB:"+yB+"距离："+distance;
									    logger.info(message);*/
									    if(distance < clashDistance) {
									    	if(!isDetail) {
									    		Map<String, Object> temp= new HashMap<String, Object>();
									    		temp.put("isClash", true);
									    		clashMap.put("isClash", temp);
									    		break forOut;
									    	}else {
									    		//Map<String, Map> clashMap = taskByTimeMap.get(String.valueOf(timeA)).get("clash");
									    		Map<String, Object> routeClashMap = taskByTimeMap.get(String.valueOf(timeA)).get("routeClash");
									    		routeClashMap.put(taskIdA, taskNameA);
									    		routeClashMap.put(taskIdB, taskNameB);
									    		taskByTimeMap.get(String.valueOf(timeA)).put("routeClash", routeClashMap);
									    		//break forTime;
									    	}
									    }
									    //判断车队距离冲突--end
									    //设备抢占冲突 -- start
									    Map<String, RltRouteDevice> videoMapB = (Map<String, RltRouteDevice>)objectMapB.get("videoMap");
									    Map<String, RltRouteDevice> signalMapB = (Map<String, RltRouteDevice>)objectMapB.get("signalMap");
									    //videoList
									    for (Map.Entry<String, RltRouteDevice> m : videoMapA.entrySet()) {
									    	double distanceVideoA = m.getValue().getDeviceLength() - distanceStartLengthA;//当前A位置与设备的距离
									    	if(distanceVideoA > -lockDistance && distanceVideoA < lockDistance) {
									    		if(videoMapB.containsKey(m.getKey())) {//视频点位冲突
									    			double distanceVideoB = videoMapB.get(m.getKey()).getDeviceLength() - distanceStartLengthB;//当前B位置与设备的距离
									    			if(distanceVideoB > -lockDistance && distanceVideoB < lockDistance) {
									    				Map<String, Object> videoClashMap = taskByTimeMap.get(String.valueOf(timeA)).get("videoClash");
											    		videoClashMap.put(taskIdA, taskNameA);
											    		videoClashMap.put(taskIdB, taskNameB);
											    		videoClashMap.put("ID"+m.getKey(), m.getValue());
											    		taskByTimeMap.get(String.valueOf(timeA)).put("videoClash", videoClashMap);
											    		//break forTime;
									    			}
										    	}
									    	}
									    }
									    for (Map.Entry<String, RltRouteDevice> m : signalMapA.entrySet()) {
									    	double distanceSignalA = m.getValue().getDeviceLength() - distanceStartLengthA;//当前A位置与设备的距离
									    	if(distanceSignalA > -lockDistance && distanceSignalA < lockDistance) {
									    		if(signalMapB.containsKey(m.getKey())) {//信号机冲突
									    			double distanceSignalB = signalMapA.get(m.getKey()).getDeviceLength() - distanceStartLengthB;//当前B位置与设备的距离
									    			if(distanceSignalB > -lockDistance && distanceSignalB < lockDistance) {
									    				Map<String, Object> signalClashMap = taskByTimeMap.get(String.valueOf(timeA)).get("signalClash");
											    		signalClashMap.put(taskIdA, taskNameA);
											    		signalClashMap.put(taskIdB, taskNameB);
											    		signalClashMap.put("ID"+m.getKey(), m.getValue());
											    		taskByTimeMap.get(String.valueOf(timeA)).put("signalClash", signalClashMap);
											    		//break forTime;
									    			}
										    	}
									    	}
									    }
								    }
						    	}
						    }
						}
				    }
				}
				//不需要详细冲突信息时，直接跳出本轮循环
				if(!isDetail) {
					continue;
				}
				//线路、视频、信号机冲突信息
				Map<String, Object> routeClashMap = taskByTimeMap.get(String.valueOf(timeA)).get("routeClash");
				Map<String, Object> videoClashMap = taskByTimeMap.get(String.valueOf(timeA)).get("videoClash");
	    		Map<String, Object> signalClashMap = taskByTimeMap.get(String.valueOf(timeA)).get("signalClash");
    			
    			//整合线路冲突信息
    			if(routeClashMap != null && !routeClashMap.isEmpty()) {
    				String timeStr = TimeHelper.dateToLongString(new Date(timeA));
    				double rout = (timeA-minBeginLong)*1.0d/allTimeLong;//当前进度
	    			if("".equals(routeClashFlag)) {
	    				routeClashFlag = "route_"+String.valueOf(timeA);
	    				Map<String, Object> temp= new HashMap<String, Object>();
	    				temp.put("startTime", timeStr);
	    				temp.put("startRout", rout);
	    				temp.put("clashType", EnumDicPublic.WRAN_DISTANCE_CLASH.getKey());
	    				temp.put("clashTypeName", EnumDicPublic.WRAN_DISTANCE_CLASH.getValue());
	    				clashMap.put(routeClashFlag, temp);
	    			}
	    			clashMap.get(routeClashFlag).put("endTime", timeStr);
	    			clashMap.get(routeClashFlag).put("endRout", rout);
	    			clashMap.get(routeClashFlag).putAll(routeClashMap);
	    		}else {
	    			//该阶段冲突结束
	    			if(!"".equals(routeClashFlag)) {
	    				routeClashFlag = "";
	    			}
	    		}
    			//整合视频点位冲突信息
    			if(videoClashMap != null && !videoClashMap.isEmpty()) {
    				String timeStr = TimeHelper.dateToLongString(new Date(timeA));
    				double rout = (timeA-minBeginLong)*1.0d/allTimeLong;//当前进度
	    			if("".equals(videoClashFlag)) {
	    				videoClashFlag = "video_"+String.valueOf(timeA);
	    				Map<String, Object> temp= new HashMap<String, Object>();
	    				temp.put("startTime", timeStr);
	    				temp.put("startRout", rout);
	    				temp.put("clashType", EnumDicPublic.WRAN_VIDEO_CLASH.getKey());
	    				temp.put("clashTypeName", EnumDicPublic.WRAN_VIDEO_CLASH.getValue());
	    				clashMap.put(videoClashFlag, temp);
	    			}
	    			clashMap.get(videoClashFlag).put("endTime", timeStr);
	    			clashMap.get(videoClashFlag).put("endRout", rout);
	    			clashMap.get(videoClashFlag).putAll(videoClashMap);
	    		}else {
	    			//该阶段冲突结束
	    			if(!"".equals(videoClashFlag)) {
	    				videoClashFlag = "";
	    			}
	    		}
	    		//整合信号机冲突信息
    			if(signalClashMap != null && !signalClashMap.isEmpty()) {
    				String timeStr = TimeHelper.dateToLongString(new Date(timeA));
    				double rout = (timeA-minBeginLong)*1.0d/allTimeLong;//当前进度
	    			if("".equals(signalClashFlag)) {
	    				signalClashFlag = "signal_"+String.valueOf(timeA);
	    				Map<String, Object> temp= new HashMap<String, Object>();
	    				temp.put("startTime", timeStr);
	    				temp.put("startRout", rout);
	    				temp.put("clashType", EnumDicPublic.WRAN_SIGNAL_CLASH.getKey());
	    				temp.put("clashTypeName", EnumDicPublic.WRAN_SIGNAL_CLASH.getValue());
	    				clashMap.put(signalClashFlag, temp);
	    			}
	    			clashMap.get(signalClashFlag).put("endTime", timeStr);
	    			clashMap.get(signalClashFlag).put("endRout", rout);
	    			clashMap.get(signalClashFlag).putAll(signalClashMap);
	    		}else {
	    			//该阶段冲突结束
	    			if(!"".equals(signalClashFlag)) {
	    				signalClashFlag = "";
	    			}
	    		}
    			long time2 = new Date().getTime();

    			String time3 = TimeHelper.dateToLongString();
    			//System.out.println(TimeHelper.dateToLongString(new Date(timeA))+" 拆分分析循环时间"+ (time2 - time1) +"ms,开始"+time0+"--结束"+time3);
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return clashMap;
	}
	
	/**
	 * 转化整合的冲突信息(Map to List)
	 * @param schemeList
	 */
	public static Map<String, Object> getClashInfoByChange(Map<String, Object> tempClashMap) {
		Map<String, Object> clashInfoMap = new HashMap<String, Object>();
		try {
			String startTime = (String)tempClashMap.get("startTime");
			String endTime = (String)tempClashMap.get("endTime");
			double startRout = (double)tempClashMap.get("startRout");
			double endRout = (double)tempClashMap.get("endRout");
			String clashType = (String)tempClashMap.get("clashType");
			String clashTypeName = (String)tempClashMap.get("clashTypeName");
			List<String> taskNameList = new ArrayList<String>();
			List<RltRouteDevice> deviceList = new ArrayList<RltRouteDevice>();
			String clashContent = "";
			String taskNameStr = "";
			String deviceStr = "";
			for (Map.Entry<String, Object> m : tempClashMap.entrySet()) {
				if(m.getKey().indexOf("T")==0) {
					taskNameList.add((String)m.getValue());
					taskNameStr += (String)m.getValue() + "、";
				}else if(m.getKey().indexOf("ID")==0) {
					deviceList.add((RltRouteDevice)m.getValue());
					deviceStr += ((RltRouteDevice)m.getValue()).getDeviceName() + "、";
				}
			}
			if("".equals(deviceStr)) {
				clashContent = clashTypeName + ":(任务)" + taskNameStr.substring(0, taskNameStr.length()-1) + "。";
			}else {
				clashContent = clashTypeName + ":(任务)" + taskNameStr.substring(0, taskNameStr.length()-1) 
							 + "，(设备)" + deviceStr.substring(0, deviceStr.length()-1) + "。"; 
			}
			clashInfoMap.put("clashType", clashType);
			clashInfoMap.put("startTime", startTime);
			clashInfoMap.put("endTime", endTime);
			clashInfoMap.put("startRout", startRout);
			clashInfoMap.put("endRout", endRout);
			clashInfoMap.put("taskNameList", taskNameList);
			clashInfoMap.put("deviceList", deviceList);
			clashInfoMap.put("clashContent", clashContent);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return clashInfoMap;
	}
	/**
	 * 监测执行任务时、预测执行冲突
	 */
	public static Map<String, Object> executePredictClash(Map<String, Object> tempClashMap) {
		Map<String, Object> clashInfoMap = new HashMap<String, Object>();
		try {
			String startTime = (String)tempClashMap.get("startTime");
			String endTime = (String)tempClashMap.get("endTime");
			double startRout = (double)tempClashMap.get("startRout");
			double endRout = (double)tempClashMap.get("endRout");
			String clashType = (String)tempClashMap.get("clashType");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return clashInfoMap;
	}
}
